#include "aht30.h"

uint8_t aht30_databyte[7];

/**
 * @brief 初始化I2C通信引脚，等待上电5ms。
 * @param	无
 * @retval	无
 */

void aht30_init(void)
{
  // myi2c_init();
  HAL_Delay(5);
}

/**
 * @brief CRC8位校验函数，返回值跟接收到的CRC校验码比价确认传输无误。
 * @param	*message	存储接收到的数据数组指针
 * @param	Num			接收到的字节个数(不包含CRC校验字节)
 * @retval	无
 */

static unsigned char calc_crc8(unsigned char *message, unsigned char Num)
{
  unsigned char i;
  unsigned char byte;
  unsigned char crc = 0xFF;

  for (byte = 0; byte < Num; byte++) {
    crc ^= (message[byte]);
    for (i = 8; i > 0; --i) {
      if (crc & 0x80)
        crc = (crc << 1) ^ 0x31;
      else
        crc = (crc << 1);
    }
  }
  return crc;
}

/**
 * @brief	重置AHT30开始测温
 * @param	无
 * @retval	无
 */

static void aht30_reset(void)
{
  myi2c_start();
  myi2c_sendbyte(0x70);
  myi2c_receiveack();
  myi2c_sendbyte(0xAC);
  myi2c_receiveack();
  myi2c_sendbyte(0x33);
  myi2c_receiveack();
  myi2c_sendbyte(0x00);
  myi2c_receiveack();
  myi2c_stop();
  HAL_Delay(80);
}

/**
 * @brief	启动AHT30并解算数据，用于刷新温湿度数据。
 * @param	无
 * @retval	返回值为1代表校验成功数据可用，为0代表校验失败数据不可用。
 */

uint8_t aht30_readdata(float *humi, float *temp)
{
  uint8_t i;
  uint32_t H = 0, T = 0;

  if (humi == NULL || temp == NULL) return 0;

  aht30_reset();
  myi2c_start();
  myi2c_sendbyte(0x71);
  myi2c_receiveack();
  for (i = 0; i < 7; i++) {
    if (i != 6) {
      aht30_databyte[i] = myi2c_receivebyte();
      myi2c_sendack(0);
    } else {
      aht30_databyte[i] = myi2c_receivebyte();
      myi2c_sendack(1);
    }
  }
  myi2c_stop();

  if ((calc_crc8(aht30_databyte, 6) != aht30_databyte[6])) return 0;

  H |= aht30_databyte[1];
  H <<= 8;
  H |= aht30_databyte[2];
  H <<= 8;
  H |= aht30_databyte[3];
  H >>= 4;

  T |= aht30_databyte[3] & 0x0F;
  T <<= 8;
  T |= aht30_databyte[4];
  T <<= 8;
  T |= aht30_databyte[5];

  *temp = (float)T * 200.0 / 1024.0 / 1024.0 - 50.0;
  *humi = (float)H / 1024.0 / 1024.0 * 100;

  return 1;
}